#pragma once

/**
 * @file me_order.h
 * @brief 匹配引擎订单结构定义
 * @details 定义了匹配引擎用于表示限价订单簿中的订单和价格级别的数据结构
 */

#include <array>
#include <sstream>
#include "common/types.h"

using namespace Common;

namespace Exchange {
  /**
   * @namespace Exchange
   * @brief 交易所相关功能的命名空间
   */
  /**
   * @struct MEOrder
   * @brief 匹配引擎用于表示限价订单簿中的单个订单
   * @details 存储订单的各种属性，包括证券ID、客户ID、订单ID、价格、数量等，并作为双向链表节点
   */
  struct MEOrder {
    TickerId ticker_id_ = TickerId_INVALID;      /**< 证券ID */
    ClientId client_id_ = ClientId_INVALID;      /**< 客户ID */
    OrderId client_order_id_ = OrderId_INVALID;  /**< 客户订单ID */
    OrderId market_order_id_ = OrderId_INVALID;  /**< 市场订单ID */
    Side side_ = Side::INVALID;                  /**< 交易方向（买/卖） */
    Price price_ = Price_INVALID;                /**< 价格 */
    Qty qty_ = Qty_INVALID;                      /**< 数量 */
    Priority priority_ = Priority_INVALID;       /**< 优先级 */

    /**
     * @brief MEOrder也作为价格级别中所有订单的双向链表节点，按FIFO顺序排列
     */
    MEOrder *prev_order_ = nullptr;  /**< 指向前一个订单的指针 */
    MEOrder *next_order_ = nullptr;  /**< 指向后一个订单的指针 */

    /// Only needed for use with MemPool.
    MEOrder() = default;

    /**
     * @brief 构造函数
     * @param ticker_id 证券ID
     * @param client_id 客户ID
     * @param client_order_id 客户订单ID
     * @param market_order_id 市场订单ID
     * @param side 交易方向
     * @param price 价格
     * @param qty 数量
     * @param priority 优先级
     * @param prev_order 前一个订单
     * @param next_order 后一个订单
     */
    MEOrder(TickerId ticker_id, ClientId client_id, OrderId client_order_id, OrderId market_order_id, Side side, Price price,
                     Qty qty, Priority priority, MEOrder *prev_order, MEOrder *next_order) noexcept
        : ticker_id_(ticker_id), client_id_(client_id), client_order_id_(client_order_id), market_order_id_(market_order_id), side_(side),
          price_(price), qty_(qty), priority_(priority), prev_order_(prev_order), next_order_(next_order) {}

    /**
     * @brief 将订单转换为字符串表示
     * @return 订单的字符串表示
     */
    auto toString() const -> std::string;
  };

  /**
   * @brief 从订单ID到MEOrder的哈希映射
   * @details 用于快速根据订单ID查找对应的订单
   */
  typedef std::array<MEOrder *, ME_MAX_ORDER_IDS> OrderHashMap;

  /**
   * @brief 从客户ID和订单ID到MEOrder的哈希映射
   * @details 用于快速根据客户ID和订单ID查找对应的订单
   */
  typedef std::array<OrderHashMap, ME_MAX_NUM_CLIENTS> ClientOrderHashMap;

  /**
   * @struct MEOrdersAtPrice
   * @brief 匹配引擎用于表示限价订单簿中的价格级别
   * @details 内部维护了一个按FIFO顺序排列的MEOrder对象列表，并作为价格级别的双向链表节点
   */
  struct MEOrdersAtPrice {
    Side side_ = Side::INVALID;                  /**< 交易方向（买/卖） */
    Price price_ = Price_INVALID;                /**< 价格 */

    MEOrder *first_me_order_ = nullptr;         /**< 指向该价格级别的第一个订单 */

    /**
     * @brief MEOrdersAtPrice也作为价格级别的双向链表节点，从最积极到最不积极的价格排列
     */
    MEOrdersAtPrice *prev_entry_ = nullptr;     /**< 指向前一个价格级别的指针 */
    MEOrdersAtPrice *next_entry_ = nullptr;     /**< 指向后一个价格级别的指针 */

    /// Only needed for use with MemPool.
    MEOrdersAtPrice() = default;

    /**
     * @brief 构造函数
     * @param side 交易方向
     * @param price 价格
     * @param first_me_order 第一个订单
     * @param prev_entry 前一个价格级别
     * @param next_entry 后一个价格级别
     */
    MEOrdersAtPrice(Side side, Price price, MEOrder *first_me_order, MEOrdersAtPrice *prev_entry, MEOrdersAtPrice *next_entry)
        : side_(side), price_(price), first_me_order_(first_me_order), prev_entry_(prev_entry), next_entry_(next_entry) {}

    /**
     * @brief 将价格级别转换为字符串表示
     * @return 价格级别的字符串表示
     */
    auto toString() const {
      std::stringstream ss;
      ss << "MEOrdersAtPrice["
         << "side:" << sideToString(side_) << " "
         << "price:" << priceToString(price_) << " "
         << "first_me_order:" << (first_me_order_ ? first_me_order_->toString() : "null") << " "
         << "prev:" << priceToString(prev_entry_ ? prev_entry_->price_ : Price_INVALID) << " "
         << "next:" << priceToString(next_entry_ ? next_entry_->price_ : Price_INVALID) << "]";

      return ss.str();
    }
  };

  /**
   * @brief 从价格到MEOrdersAtPrice的哈希映射
   * @details 用于快速根据价格查找对应的价格级别
   */
  typedef std::array<MEOrdersAtPrice *, ME_MAX_PRICE_LEVELS> OrdersAtPriceHashMap;
}
